package aspect

import (
	"boy-go/modules/system/model"
	"boy-go/modules/system/vo"
	"boy-go/pkg/constants"
	"boy-go/pkg/security"
	"boy-go/pkg/xmap"
	"fmt"
	"gorm.io/gorm"
	"strings"
)

var (
	DATA_SCOPE_ALL            = "1" //全部数据权限
	DATA_SCOPE_CUSTOM         = "2" //自定数据权限
	DATA_SCOPE_DEPT           = "3" //部门数据权限
	DATA_SCOPE_DEPT_AND_CHILD = "4" //部门及以下数据权限
	DATA_SCOPE_SELF           = "5" //仅本人数据权限
)

// HandleDataScope 处理数据权限
func HandleDataScope(sql *string, deptAlias string, userAlias string) {
	loginUser := security.GetLoginUser()
	if loginUser != nil {
		currentUser := loginUser.User
		if currentUser != nil && !model.IsAdmin(&currentUser.UserId) {
			whereSQL := dataScopeFilter(loginUser.User, deptAlias, userAlias, security.GetPermission())
			*sql = *sql + fmt.Sprintf(" AND (%s)", whereSQL)
		}
	}
}
func HandleDataScopeByDB(db *gorm.DB, deptAlias string, userAlias string) *gorm.DB {
	loginUser := security.GetLoginUser()
	if loginUser != nil {
		currentUser := loginUser.User
		if currentUser != nil && !model.IsAdmin(&currentUser.UserId) {
			return dataScopeFilterDB(db, loginUser.User, deptAlias, userAlias, security.GetPermission())
		}
	}
	return db
}
func dataScopeFilter(user *vo.SysUserModel, deptAlias string, userAlias string, permission *string) string {
	sqlString := ""
	conditionMap := map[string]interface{}{}
	scopeCustomIds := make([]string, 0)
	for _, role := range user.Roles {
		if DATA_SCOPE_CUSTOM == *role.DataScope && *role.Status == "0" {
			_, have := role.PermissionMap[*permission]
			if have {
				scopeCustomIds = append(scopeCustomIds, fmt.Sprintf("%d", role.RoleId))
			}
		}

	}
	for _, role := range user.Roles {
		dataScope := role.DataScope
		if xmap.Contains(conditionMap, *dataScope) || *role.Status == constants.ROLE_DISABLE {
			continue
		}
		if _, have := role.PermissionMap[*permission]; have == false {
			continue
		}
		if DATA_SCOPE_ALL == *dataScope {
			// 全部数据权限
			sqlString = ""
		} else if DATA_SCOPE_CUSTOM == *dataScope {
			// 自定义数据权限
			if len(scopeCustomIds) > 1 {
				sqlString += fmt.Sprintf(" OR %s.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in (%s) ) ", deptAlias, strings.Join(scopeCustomIds, ","))
			} else {
				sqlString += fmt.Sprintf(" OR %s.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = %s ) ", deptAlias, scopeCustomIds[0])
			}
		} else if DATA_SCOPE_DEPT == *dataScope {
			// 本部门数据权限
			sqlString += fmt.Sprintf(" OR %s.dept_id = %d ", deptAlias, *user.DeptId)
		} else if DATA_SCOPE_DEPT_AND_CHILD == *dataScope {
			// 本部门及以下数据权限
			sqlString += fmt.Sprintf(" OR %s.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = %d or find_in_set( %d , ancestors ) )", deptAlias, *user.DeptId, *user.DeptId)
		} else if DATA_SCOPE_SELF == *dataScope {
			// 仅本人数据权限
			if userAlias != "" {
				sqlString += fmt.Sprintf(" OR %s.user_id = %d", userAlias, user.UserId)
			} else {
				// 数据权限为仅本人且没有userAlias别名不查询任何数据
				sqlString += fmt.Sprintf(" OR %s.dept_id = 0", deptAlias)
			}
		}
		conditionMap[*dataScope] = true
	}
	//角色都不包含传递过来的权限字符，这个时候sqlString也会为空，所以要限制一下,不查询任何数据
	if len(conditionMap) == 0 {
		sqlString += fmt.Sprintf(" OR %s.dept_id = 0", deptAlias)
	}
	return sqlString[4:]
}
func dataScopeFilterDB(db *gorm.DB, user *vo.SysUserModel, deptAlias string, userAlias string, permission *string) *gorm.DB {
	db = db.Where(dataScopeFilter(user, deptAlias, userAlias, permission))
	return db
}
